﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace eStore.Models
{
    public class ProductRepository:IProductRepository
    {
        private eStoreContainer _container;

        public ProductRepository() {
            _container = new eStoreContainer();
        }


        public  void Add(Product objT)
        {
            try
            {
                _container.AddToProducts(objT);
                _container.SaveChanges();
            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public  void Remove(Product objT)
        {
            try
            {
                
                _container.Products.DeleteObject(objT);
                _container.SaveChanges();
            }
            catch (Exception)
            {
                
                throw;
            }
            
        }

        public  void Update(Product objT)
        {
            Product oMatchProduct = _container.Products.Single((x) => x.ProductId==objT.ProductId);

        }

        public  Product GetById(int iID)
        {
            Product singleOrDefault = _container.Products.SingleOrDefault((x) => x.ProductId == iID);
            return singleOrDefault;
        }

        public  Product GetById(string sID)
        {
            int iID = Int32.Parse(sID);
            Product singleOrDefault = _container.Products.SingleOrDefault((x) => x.ProductId == iID);
            return singleOrDefault;
        }

        public  IEnumerable<Product> GetTopRated(int? iTop)
        {
            int iTopCount = iTop ?? iTop.Value;
  

  
            var topRatedProducts = (from product in _container.Products.Include("ProductReviews")
                                    orderby product.ProductReviews.Average((x) => x.StarRate) descending
                                    select product).Distinct((y) => y.ProductName);


            return topRatedProducts.Take(iTopCount);
        }

        public IEnumerable<Product> GetTop5RatedProduct()
        {
            return GetTopRated(5);
        }




        public IEnumerable<Product> GetTopLatestProduct()
        {
            return GetLatest(6);
        }

        public IEnumerable<Product> GetLatest(int? iTopLatest)
        {
            int iTopLatestCnt = iTopLatest ?? iTopLatest.Value;

            var topLatestProduct = (from singleproduct in _container.Products.Include("ProductReviews")
                                    orderby singleproduct.CreatedDate descending
                                    select singleproduct);


            return topLatestProduct;
        }


        public IEnumerable<Product> GetAll()
        {
            var allProducts = _container.Products.ToList();
            return allProducts;
        }


        public IEnumerable<Product> FindProductByTextWildCard(string sText)
        {
            var sLowerText = sText.ToLower();
            var allMatchedProducts = from product in _container.Products.Include("ProductReviews")
                                     where product.ProductName.ToLower().Contains(sLowerText) ||
                                     product.ProductDesc.ToLower().Contains(sLowerText) ||
                                     product.ProductReviews.Any((x) => x.ReviewComment.ToLower().Contains(sLowerText))
                                     select product;

            return allMatchedProducts;
        }

        public IEnumerable<Product> FindProductByTextCaseSensitive(string sText)
        {
            var allMatchedProducts = from product in _container.Products.Include("ProductReviews")
                                     where product.ProductName.Contains(sText) ||
                                     product.ProductDesc.Contains(sText) ||
                                     product.ProductReviews.Any((x) => x.ReviewComment.Contains(sText))
                                     select product;

            return allMatchedProducts;
        }
    }
}